package cc.rengu.igas.bomp.core.service.trans;

import cc.rengu.igas.bomp.common.dao.*;
import cc.rengu.igas.bomp.common.dao.impl.*;
import cc.rengu.igas.bomp.common.entity.*;
import cc.rengu.igas.bomp.common.enums.RespCodeEnum;
import cc.rengu.igas.bomp.core.service.base.ManageService;
import cc.rengu.igas.bomp.facade.request.TermInfoReportOrUpdateRequest;
import cc.rengu.igas.bomp.facade.response.TermInfoReportOrUpdateResponse;
import cc.rengu.igas.share.common.constant.ShareParamConstant;
import cc.rengu.igas.share.common.constant.TransCacheConstant;
import cc.rengu.igas.share.core.model.MchntInfo;
import cc.rengu.igas.share.core.model.MchntTermInfo;
import cc.rengu.oltp.service.base.ChannelBaseService;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.entity.ChannelCallCfg;
import cc.rengu.oltp.service.common.enums.CheckResultEnum;
import cc.rengu.oltp.service.common.enums.TransStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.OrderInfo;
import cc.rengu.oltp.service.realize.TransCustomImpl;
import cc.rengu.oltp.utility.util.*;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 终端信息报备及更新服务（目前支持 银联AT终端信息采集）
 * 默认终端支持微信、支付宝
 *
 * @author yangfan
 * @version 1.0
 * @date 2022/3/21
 */
public class TermInfoReportOrUpdateService extends ManageService implements TransCustomImpl {

    @Override
    protected Object bizBeforeCust() throws Exception {
        TermInfoReportOrUpdateRequest termInfoReportOrUpdateRequest = new TermInfoReportOrUpdateRequest();
        ConvertUtil.convertOutput(termInfoReportOrUpdateRequest);
        return termInfoReportOrUpdateRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        TermInfoReportOrUpdateRequest termInfoReportOrUpdateRequest = (TermInfoReportOrUpdateRequest) request;
        BizResponse<TermInfoReportOrUpdateResponse> bizResponse = new BizResponse<>();
        TermInfoReportOrUpdateResponse termInfoReportOrUpdateResponse = new TermInfoReportOrUpdateResponse();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setResult(termInfoReportOrUpdateResponse);
        String instId = termInfoReportOrUpdateRequest.getHeader().getInstId();
        String userId = termInfoReportOrUpdateRequest.getUserId();
        String mchntNo = termInfoReportOrUpdateRequest.getMchntNo();
        String termNo = termInfoReportOrUpdateRequest.getTermNo();
        String opType = termInfoReportOrUpdateRequest.getOpType();
        String termState = termInfoReportOrUpdateRequest.getTermState();

        /* Step1:参数合法性检查 */
        if (StringUtil.isEmptyOrNull(instId) || StringUtil.isEmptyOrNull(userId) || StringUtil.isEmptyOrNull(mchntNo) ||
                StringUtil.isEmptyOrNull(termNo) || StringUtil.isEmptyOrNull(opType)) {
            rglog.error("必填性校验失败! instId:<{}>,userId:<{}>,mchntNo:<{}>,termNo<{}>,opType<{}>", instId, userId, mchntNo, termNo, opType);
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }

        /* Step2:获取商户信息 */
        /* Step2.1:获取商户基本信息 */
        MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
        MchntBaseInfo mchntBaseInfo = mchntBaseInfoMapper.selectMchntBaseInfoByPrimaryKey(instId, mchntNo);
        if (null == mchntBaseInfo) {
            rglog.error("获取商户基本信息失败,instId:<{}>,mchntNo:<{}>", instId, mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        /* Step2.2:获取微信商户信息 */
        WechatMchntInfoMapper wechatMchntInfoMapper = new WechatMchntInfoMapperImpl();
        WechatMchntInfo wechatMchntInfo = wechatMchntInfoMapper.selectWechatMchntInfoByPrimaryKey(instId, mchntNo);
        if (null == wechatMchntInfo) {
            rglog.warn("获取微信商户信息为空,instId:<{}>,mchntNo:<{}>", instId, mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        /* Step2.3:获取支付宝商户信息 */
        AlipayMchntInfoMapper alipayMchntInfoMapper = new AlipayMchntInfoMapperImpl();
        AlipayMchntInfo alipayMchntInfo = alipayMchntInfoMapper.selectAlipayMchntInfoByPrimaryKey(instId, mchntNo);
        if (null == alipayMchntInfo) {
            rglog.warn("获取支付宝商户信息为空,instId:<{}>,mchntNo:<{}>", instId, mchntNo);
            throw new BizException(RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespCode(), RespCodeEnum.MCHNT_INFO_NOT_FOUND.getRespDesc());
        }
        /* Step2.4:商户信息赋值 */
        MchntInfo mchntInfo = new MchntInfo();
        BeanUtil.beanCopy(mchntBaseInfo, mchntInfo);
        mchntInfo.setWechatMchntNo(wechatMchntInfo.getWechatMchntNo());
        mchntInfo.setWechatChannelType(wechatMchntInfo.getDstChannelType());
        mchntInfo.setAlipayMchntNo(alipayMchntInfo.getAlipayMchntNo());
        mchntInfo.setAlipayChannelType(alipayMchntInfo.getDstChannelType());

        /* Step3:获取终端信息 */
        TermInfoMapper termInfoMapper = new TermInfoMapperImpl();
        TermInfo termInfo = termInfoMapper.selectBompTermInfoByPrimaryKey(instId, mchntNo, termNo);
        if (null == termInfo) {
            rglog.error("获取终端信息失败,instId:<{}>,mchntNo:<{}>,termNo:<{}>", instId, mchntNo, termNo);
            throw new BizException(RespCodeEnum.QUERY_TERMINFO_ERROR.getRespCode(), RespCodeEnum.QUERY_TERMINFO_ERROR.getRespDesc());
        }
        // 将需要解析的终端信息设置到交易缓存中
        GlobalTransUtil.setCacheValue(TransCacheConstant.TERM_INFO, termInfo);

        /* Step4:调用通道接口 */
        String mchntTermInfoKey = TransCacheConstant.TERM_INFO + "_" + mchntNo + "_" + termNo;
        MchntTermInfo mchntTermInfo = new MchntTermInfo();
        BeanUtil.beanCopy(termInfo, mchntTermInfo);
        mchntTermInfo.setTermSn(termInfo.getSn());
        GlobalTransUtil.setCacheValue(mchntTermInfoKey, mchntTermInfo);
        String mchntInfoKey = TransCacheConstant.MCHNT_INFO + "_" + mchntNo;
        GlobalTransUtil.setCacheValue(mchntInfoKey, mchntInfo);
        String mchntBizProvinceName = getRegionName(mchntBaseInfo.getMchntBizProvince());
        String mchntBizCityName = getRegionName(mchntBaseInfo.getMchntBizCity());
        String mchntBizRegionName = getRegionName(mchntBaseInfo.getMchntBizRegion());
        xmlTreeUtil.setXmlTreeStringValue("mchntBizProvinceName", mchntBizProvinceName);
        xmlTreeUtil.setXmlTreeStringValue("mchntBizCityName", mchntBizCityName);
        xmlTreeUtil.setXmlTreeStringValue("mchntBizRegionName", mchntBizRegionName);
        if (null == txnInfo.getChannelCallCfgList() || txnInfo.getChannelCallCfgList().isEmpty()) {
            rglog.error("<{}-{}>交易未配置交易通道服务调用配置信息！", txnInfo.getSrcTxnAuthCfg().getTxnNum(), txnInfo.getSrcTxnAuthCfg().getTxnName());
            throw new BizException(RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespCode(), RespCodeEnum.CHANNEL_CONFIG_NOT_EXIST.getRespDesc());
        }
        List<ChannelCallCfg> channelCallCfgList = txnInfo.getChannelCallCfgList().stream().filter(item ->
                item.getCallIndex().equals(ChannelBaseService.FIRST_CHANNEL_CALL_INDEX)).collect(Collectors.toList());
        ChannelCallCfg channelCallCfg = channelCallSceneDiscern(termInfoReportOrUpdateRequest, channelCallCfgList);
        Class channelClasz = Class.forName(channelCallCfg.getCallChannelImpl());
        ChannelBaseService channelBaseService = (ChannelBaseService) channelClasz.newInstance();
        channelBaseService.callService(txnInfo, null, channelCallCfg.getBizScene(), request);

        /* Step5:组装应答信息 */
        termInfoReportOrUpdateResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        termInfoReportOrUpdateResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(termInfoReportOrUpdateResponse);
        return bizResponse;
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        TermInfoReportOrUpdateResponse termInfoReportOrUpdateResponse = (TermInfoReportOrUpdateResponse) bizResponse.getResult();
        ConvertUtil.convertInput(termInfoReportOrUpdateResponse);
    }

    @Override
    public ChannelCallCfg channelCallSceneDiscern(Object request, List<ChannelCallCfg> channelCallCfgList) throws Exception {
        Optional<ChannelCallCfg> channelCallCfgOpt = channelCallCfgList.stream().filter(item ->
                item.getBizScene().equals(ShareParamConstant.CALL_CFG_DEFAULT_BIZ_SCENE)).findFirst();
        return channelCallCfgOpt.orElse(null);
    }

    @Override
    public CheckResultEnum channelCallPreCheck(Object request, ChannelCallCfg channelCallCfg, OrderInfo orderInfo) throws Exception {
        return CheckResultEnum.PASSED;
    }

    @Override
    public TransStatusEnum channelCallResultProc(Object request, ChannelCallCfg channelCallCfg, TransStatusEnum transStatusEnum, Object channelResponse, OrderInfo needUpdateOrderInfo) throws Exception {
        TermInfo termInfo = (TermInfo) GlobalTransUtil.getCacheValue(TransCacheConstant.TERM_INFO);
        if (TransStatusEnum.TRANS_SUCC.equals(transStatusEnum) && null != channelResponse) {
            if (null != termInfo) {
                rglog.info("终端信息报备/更新成功,更新终端信息-报备状态：00-未报备 01-已报备");
                termInfo.setReserve2("01");
                TermInfoMapper termInfoMapper = new TermInfoMapperImpl();
                int dbResult = termInfoMapper.updateBompTermInfoByPrimaryKey(termInfo, "04");
                if (dbResult != 0) {
                    rglog.error("更新终端信息-报备状态失败！,instId:<{}>,mchntNo:<{}>,termNo:<{}>", termInfo.getInstId(), termInfo.getMchntNo(), termInfo.getTermNo());
                    throw new BizException(RespCodeEnum.DATABASE_OPR_ERROR.getRespCode(), RespCodeEnum.DATABASE_OPR_ERROR.getRespDesc());
                }
            }
        }
        return transStatusEnum;
    }

    /**
     * 根据业务主键查询行政区划代码信息
     *
     * @param regionCode 行政区划代码
     * @return 行政区划名称
     * @throws Exception 异常
     */
    private String getRegionName(String regionCode) throws Exception {
        /* 获取行政区划名称 */
        String regionName = "";
        RegionInfoMapper regionInfoMapper = new RegionInfoMapperImpl();
        RegionInfo regionInfo = regionInfoMapper.selectRegionInfoByPrimaryKey(regionCode);
        if (null != regionInfo) {
            regionName = regionInfo.getRegionName();
        }
        return regionName;
    }
}
